using System;
using System.Collections;
using System.Collections.Generic;
using GameFramework.common;
using GameFramework.events;
using GameFramework.timer;
using UnityEngine;
using UnityEngine.AddressableAssets;
using Event = GameFramework.events.Event;

public class EventManager : Singleton<EventManager>
{
    private Dictionary<Type, List<Action<Event>>> _listeners = new Dictionary<Type, List<Action<Event>>>();
    private List<Event> asyncEvents = new List<Event>();

    public EventManager()
    {
        TimerManager.Instance.schedule(timer =>
        {
            //TODO 使用阻塞队列弹栈是不是好点
            int eventsCount = asyncEvents.Count;
            if (eventsCount <= 0) return;
            List<Event> temp = new List<Event>();
            for (int i = 0; i < eventsCount; i++)
            {
                temp.Add(asyncEvents[i]);
            }

            asyncEvents.RemoveRange(0, eventsCount);
            foreach (Event e in temp)
            {
                dispatch(e);
            }
        }, 0, -1);//每帧都检测
    }

    public void rigisterListener<T>(Action<Event> listener) where T : Event
    {
        Type eventType = typeof(T);
        if (!typeof(Event).IsAssignableFrom(eventType))
        {
            Debug.LogError("无法注册非Event类型的事件：" + eventType.Name);
            return;
        }

        if (!_listeners.ContainsKey(eventType))
        {
            _listeners.Add(eventType, new List<Action<Event>>());
        }

        _listeners[eventType].Add(listener);
    }
    /// <summary>
    /// 添加事件监听
    /// </summary>
    /// <param name="eventType"></param>
    /// <param name="listener"></param>
    public void rigisterListener(Type eventType, Action<Event> listener)
    {
        if (!typeof(Event).IsAssignableFrom(eventType))
        {
            Debug.LogError("无法注册非Event类型的事件：" + eventType.Name);
            return;
        }

        if (!_listeners.ContainsKey(eventType))
        {
            _listeners.Add(eventType, new List<Action<Event>>());
        }

        _listeners[eventType].Add(listener);
    }

    /// <summary>
    /// 移除事件监听器
    /// </summary>
    /// <param name="eventType"></param>
    /// <param name="listener"></param>
    public void removeListener(Type eventType, Action<Event> listener)
    {
        if (!typeof(Event).IsAssignableFrom(eventType))
        {
            Debug.LogError("无法取消非Event类型的事件：" + eventType.Name);
            return;
        }

        if (!_listeners.ContainsKey(eventType))
        {
            return;
        }

        List<Action<Event>> listeners = _listeners[eventType];
        if (listeners.Count == 0)
        {
            _listeners.Remove(eventType);
            return;
        }

        listeners.Remove(listener);
        if (listeners.Count == 0)
        {
            _listeners.Remove(eventType);
        }
    }

    /// <summary>
    /// 同步分发事件
    /// //TODO event对象放入对象池中
    /// </summary>
    /// <param name="nowEvent"></param>
    public void dispatch(Event nowEvent)
    {
        if (!_listeners.ContainsKey(nowEvent.GetType()))
        {
            return;
        }

        var listeners = _listeners[nowEvent.GetType()];
        for (var i = 0; i < listeners.Count; i++)
        {
            try
            {
                listeners[i].Invoke(nowEvent);
            }
            catch (Exception e)
            {
                Debug.LogError(e);
            }
        }
    }

    //TODO 异步分发事件
    public void dispatchAsync(Event nowEvent)
    {
        asyncEvents.Add(nowEvent);
    }

    private void Update()
    {
        if (asyncEvents.Count == 0)
        {
            return;
        }

        asyncEvents.ForEach(e => dispatch(e));
        asyncEvents.Clear();
    }
}